package com.example.server.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.server.web.domain.Class;
import com.example.server.web.domain.Student;
import com.example.server.web.domain.SysUser;
import com.example.server.web.domain.dto.*;
import com.example.server.web.domain.page.PageQueryDto;
import com.example.server.web.domain.vo.StudentVo;
import com.example.server.web.exception.CustomException;
import com.example.server.web.mapper.StudentMapper;
import com.example.server.web.service.ClassService;
import com.example.server.web.service.StudentService;
import com.example.server.web.service.SysUserService;
import com.example.server.web.utils.MyObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 作者
 * @since 2023-04-04
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ClassService classService;


    @Override
    public Page<StudentDto> getStuPage(PageQueryDto pageQueryDto) {
        Integer page = pageQueryDto.getPage();
        Integer limit = pageQueryDto.getLimit();
        Integer classId = null;
        String username = "";
        String name = " ";

        classId = (Integer) pageQueryDto.getParams("classId");
        name = (String) pageQueryDto.getParams("name");
        username = (String) pageQueryDto.getParams("username");

        if(classId==null){
            throw new CustomException("查找班级不能为空");
        }

        Page<StudentDto> p = new Page<>(page,limit);
        p.setRecords(studentMapper.showClassStudent(Long.valueOf(classId),username,name,(page-1)*limit,limit));
        p.setTotal(studentMapper.getTotal(Long.valueOf(classId),username,name));
        return p;
    }

    @Override
    public Integer addStudent(List<Student> students) {
        Integer count = 0;
        for (Student s:students) {
            studentMapper.updateById(s);
            count ++;
        }
        return count;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer removeStudent(List<Long> studentList) {
        for (Long id : studentList) {
            Student student = studentMapper.selectById(id);
            MyObjectUtils.throwExIfNull(student,"学生信息不存在，移除失败");
            //更新学生的班级id和班级名字为空
            LambdaUpdateWrapper<Student> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Student::getId,id);
            updateWrapper.set(Student::getClassId,null);
            // updateWrapper.set(Student::getClassName,null);
            boolean update = this.update(updateWrapper);
            if (!update){
                throw new CustomException("更新失败");
            }
        }
        return studentList.size();
    }

    @Override
    public Long getStuClass(Long id) {
        Student student  = studentMapper.selectById(id);
        if(student == null){
            throw new CustomException("学生id不存在");
        }
        Long classId = student.getClassId();
        return classId;
    }

    public boolean ifExistStudent(String stuId) {
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getStuId,stuId);
        boolean bool = studentMapper.selectOne(wrapper) == null ? false: true;
        System.out.println(bool);
        return bool;
    }

    @Override
    public Map<String, Object> getUser(PageQueryDto dto) {
        return null;
    }

    /**
     * 获得指定班级的所有学生
     */
    @Override
    public List<Student> getStudentsByClassId(Long classId){
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getClassId,classId);
        List<Student> students = studentMapper.selectList(wrapper);
        return students;
    }

    @Override
    public void addStudentAndUser(StudentAddDto studentAddDto) {
        SysUserDto sysUserDto = studentAddDto.getSysUserDto();
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(3L);
        sysUserDto.setRoleIds(roleIds);
        sysUserService.insertUser(sysUserDto);
        //获得用户id
        SysUser user = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUserDto.getUsername()));
        Long userId = user.getId();
        if(userId == null){
            throw new CustomException("用户添加失败");
        }
        //取出学生对象
        Student student = studentAddDto.getStudent();
        student.setStuId(user.getUsername());
        student.setUserId(userId);
        //插入
        int insert = studentMapper.insert(student);
        if(insert < 1){
            throw new CustomException("添加失败");
        }
    }

    @Override
    public Map getPage(PageQueryDto pageQueryDto, StudentParamDto studentParamDto) {
        //查询分页数据和总记录数
        Map<String, Object> map = new HashMap<>();
        Long total = studentMapper.getPageTotal(studentParamDto);
        map.put("total",total);
        if (total <= 0L) {
            map.put("list",null);
        } else {
            List<StudentVo> studentVos=studentMapper.getPage((pageQueryDto.getPage()-1)* pageQueryDto.getLimit(),pageQueryDto.getLimit(),studentParamDto);
            map.put("list",studentVos);
        }
        return map;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStudent(StudentAddDto studentAddDto) {
        //取出学生对象
        Student student = studentAddDto.getStudent();

        //取出用户对象
        SysUserDto sysUserDto = studentAddDto.getSysUserDto();
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(3L);
        sysUserDto.setRoleIds(roleIds);
        if (student.getId() == null || sysUserDto.getId() == null){
            throw new CustomException("更新失败");
        }
        //更新用户
        Integer updateUser = sysUserService.updateUser(sysUserDto,false);
        //更新学生
        int updateStudent = studentMapper.updateById(student);
        if (updateStudent < 1 || updateUser < 1){
            throw new CustomException("更新失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteStudent(List<Long> ids) {
        for (Long id : ids) {
            Student student = this.getById(id);
            MyObjectUtils.throwExIfNull(student,"学生信息不存在");
            sysUserService.deleteUser(student.getUserId());
            //获取班级id
            Long classId = student.getClassId();
            if (classId != null){
                Class aClass = classService.getById(classId);
                if (MyObjectUtils.isNotNull(aClass)){
                    LambdaUpdateWrapper<Class> wrapper = new LambdaUpdateWrapper<>();
                    wrapper.eq(Class::getId,classId);
                    wrapper.set(Class::getClassPersonNum,aClass.getClassPersonNum()-1);
                    classService.update(wrapper);
                }
            }
            //删除学生
            studentMapper.deleteById(id);
        }
    }

    @Override
    public StudentAddDto selectDetail(Long id) {
        StudentAddDto studentAddDto = new StudentAddDto();
        Student student = studentMapper.selectById(id);
        MyObjectUtils.throwExIfNull(student,"学生信息不存在");
        SysUser sysUser = sysUserService.getUserById(student.getUserId());
        MyObjectUtils.throwExIfNull(sysUser,"用户信息不存在");
        SysUserDto sysUserDto = new SysUserDto();
        BeanUtils.copyProperties(sysUser,sysUserDto);
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(3L);
        sysUserDto.setRoleIds(roleIds);


        studentAddDto.setStudent(student);
        studentAddDto.setSysUserDto(sysUserDto);

        return studentAddDto;
    }
}
